/**
 * 
 */
package hoan.nguyen.dao.impl;

import hoan.nguyen.dao.GenericDAO;

import java.io.Serializable;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;

/**
 * @author Horizon
 * 
 */
public class GenericDAOImpl<T, P extends Serializable> implements GenericDAO<T, P> {

	/**
	 * 
	 */
	private final Log log = LogFactory.getLog(getClass());
	
	/**
	 * 
	 */
	private SessionFactory sessionFactory;
	
	/**
	 * 
	 */
	private Class<T> persistentClass;

	/**
	 * @return the sessionFactory
	 */
	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	/**
	 * 
	 * @param persistentClass
	 */
	public GenericDAOImpl(final Class<T> persistentClass){
		
		this.persistentClass = persistentClass;
	}
	
	/**
	 * @param sessionFactory
	 *            the sessionFactory to set
	 */
	@Autowired
	@Required
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	/**
	 * 
	 */
	@SuppressWarnings("unchecked")
	public List<T> getAll() {

		return getCurrentSession().createQuery("from " + this.persistentClass.getName()).list();
	}

	/**
	 * 
	 */
	public List<T> getAllDistinct() {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * 
	 */
	@SuppressWarnings("unchecked")
	public T getById(P id) {

		T entity = (T) getCurrentSession().get(this.persistentClass, id);
		if(entity == null){
			log.warn(this.persistentClass + "' object with id '" + id + "' not found...");
		}
		return entity;
	}

	/**
	 * 
	 */
	public T save(final T entity) {

		getCurrentSession().save(entity);
		return entity;
	}

	/**
	 * 
	 */
	public void update(T entity) {

		getCurrentSession().saveOrUpdate(entity);
	}

	/**
	 * 
	 */
	public void delete(T entity) {

		getCurrentSession().delete(entity);
	}

	/**
	 * 
	 */
	public void deleteById(P id) {

		T entity = this.getById(id);
		if(entity != null){
			getCurrentSession().delete(entity);
		}
	}
	
	/**
	 * 
	 * @return
	 */
	protected Session getCurrentSession(){
		
		return this.sessionFactory.getCurrentSession();
	}
}
